#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
打包前准备脚本
确保系统准备好进行打包部署
"""

import os
import sys
import shutil
import json
from pathlib import Path
from datetime import datetime

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

def create_backup():
    """创建当前配置和数据的备份"""
    print("=== 创建备份 ===")
    
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    backup_dir = project_root / f"backup_before_packaging_{timestamp}"
    backup_dir.mkdir(exist_ok=True)
    
    # 备份配置文件
    config_file = project_root / "config.json"
    if config_file.exists():
        shutil.copy2(config_file, backup_dir / "config.json")
        print(f"✓ 配置文件已备份到: {backup_dir}")
    
    # 备份数据库文件（如果存在）
    data_dir = project_root / "data"
    if data_dir.exists():
        backup_data_dir = backup_dir / "data"
        shutil.copytree(data_dir, backup_data_dir)
        print(f"✓ 数据目录已备份到: {backup_data_dir}")
    
    # 备份日志文件（如果存在）
    logs_dir = project_root / "logs"
    if logs_dir.exists():
        backup_logs_dir = backup_dir / "logs"
        shutil.copytree(logs_dir, backup_logs_dir)
        print(f"✓ 日志目录已备份到: {backup_logs_dir}")
    
    return backup_dir

def prepare_clean_database():
    """准备干净的数据库"""
    print("\n=== 准备干净数据库 ===")
    
    try:
        # 强制释放数据库连接
        from src.models.database.database import dispose_global_db_manager
        dispose_global_db_manager()
        print("✓ 数据库连接已释放")
        
        # 删除现有数据库文件
        from src.core.path_manager import path_manager
        db_file = path_manager.get_database_file()
        if db_file.exists():
            db_file.unlink()
            print(f"✓ 已删除现有数据库: {db_file}")
        
        # 创建干净数据库
        from src.models.database.database import DatabaseManager
        clean_db = DatabaseManager(init_data="clean")
        print("✓ 干净数据库创建完成（仅表结构）")
        
        # 释放连接
        clean_db.dispose()
        
    except Exception as e:
        print(f"❌ 数据库准备失败: {e}")
        return False
    
    return True

def update_config_for_packaging():
    """更新配置文件以适合打包"""
    print("\n=== 更新配置文件 ===")
    
    config_file = project_root / "config.json"
    
    try:
        # 读取现有配置
        if config_file.exists():
            with open(config_file, 'r', encoding='utf-8') as f:
                config = json.load(f)
        else:
            config = {}
        
        # 更新配置以适合打包
        packaging_config = {
            "init_default_data": True,  # 首次运行时初始化默认数据
            "database_path": "data/wmssimple.db",  # 使用相对路径
            "log_level": "INFO",
            "log_file": "logs/wms.log",
            "server": {
                "host": "0.0.0.0",
                "port": 8000,
                "debug": False
            },
            "default_plates": [
                {"name": "AGV1", "capacity": 10},
                {"name": "AGV2", "capacity": 10},
                {"name": "TB1", "capacity": 10},
                {"name": "FL1", "capacity": 10}
            ]
        }
        
        # 合并配置
        config.update(packaging_config)
        
        # 写入配置文件
        with open(config_file, 'w', encoding='utf-8') as f:
            json.dump(config, f, indent=2, ensure_ascii=False)
        
        print("✓ 配置文件已更新为打包版本")
        print(f"  - 启用默认数据初始化")
        print(f"  - 使用相对路径")
        print(f"  - 生产环境配置")
        
    except Exception as e:
        print(f"❌ 配置文件更新失败: {e}")
        return False
    
    return True

def clean_development_files():
    """清理开发文件"""
    print("\n=== 清理开发文件 ===")
    
    # 要清理的文件和目录
    cleanup_patterns = [
        "__pycache__",
        "*.pyc",
        "*.pyo",
        ".pytest_cache",
        ".coverage",
        "*.log",
        "test_*.py",
        "debug_*.py"
    ]
    
    cleaned_count = 0
    
    # 递归清理
    for root, dirs, files in os.walk(project_root):
        # 清理 __pycache__ 目录
        if "__pycache__" in dirs:
            pycache_dir = Path(root) / "__pycache__"
            shutil.rmtree(pycache_dir)
            cleaned_count += 1
            print(f"✓ 清理: {pycache_dir}")
        
        # 清理 .pyc 文件
        for file in files:
            if file.endswith(('.pyc', '.pyo')):
                file_path = Path(root) / file
                file_path.unlink()
                cleaned_count += 1
    
    print(f"✓ 清理完成，共清理 {cleaned_count} 个文件/目录")

def verify_packaging_readiness():
    """验证打包准备情况"""
    print("\n=== 验证打包准备情况 ===")
    
    checks = []
    
    # 检查关键文件
    required_files = [
        "main.py",
        "config.json",
        "requirements.txt",
        "src/core/path_manager.py",
        "src/models/database/database.py",
        "src/api/api_server.py"
    ]
    
    for file_path in required_files:
        file_full_path = project_root / file_path
        if file_full_path.exists():
            checks.append(f"✓ {file_path}")
        else:
            checks.append(f"❌ {file_path} - 缺失")
    
    # 检查数据库
    try:
        from src.core.path_manager import path_manager
        db_file = path_manager.get_database_file()
        if db_file.exists():
            checks.append(f"✓ 数据库文件: {db_file}")
        else:
            checks.append(f"❌ 数据库文件不存在")
    except Exception as e:
        checks.append(f"❌ 数据库检查失败: {e}")
    
    # 检查配置
    try:
        from src.core.config import config
        if config.get("init_default_data") is not None:
            checks.append("✓ 配置文件格式正确")
        else:
            checks.append("❌ 配置文件格式错误")
    except Exception as e:
        checks.append(f"❌ 配置检查失败: {e}")
    
    # 输出检查结果
    for check in checks:
        print(check)
    
    # 统计结果
    success_count = sum(1 for check in checks if check.startswith("✓"))
    total_count = len(checks)
    
    print(f"\n检查结果: {success_count}/{total_count} 项通过")
    
    return success_count == total_count

def create_packaging_info():
    """创建打包信息文件"""
    print("\n=== 创建打包信息 ===")
    
    packaging_info = {
        "version": "v2.1.0",
        "build_date": datetime.now().isoformat(),
        "build_type": "production",
        "features": [
            "路径管理系统",
            "数据库连接优化",
            "任务追踪功能",
            "Windows服务支持",
            "Web界面",
            "REST API"
        ],
        "requirements": [
            "Python 3.8+",
            "SQLite 3.x",
            "Windows Server 2016+"
        ],
        "deployment_notes": [
            "首次运行会自动创建默认料盘数据",
            "支持Python环境、虚拟环境、exe打包环境",
            "所有路径自动适配部署环境",
            "包含完整的诊断和管理工具"
        ]
    }
    
    info_file = project_root / "PACKAGING_INFO.json"
    with open(info_file, 'w', encoding='utf-8') as f:
        json.dump(packaging_info, f, indent=2, ensure_ascii=False)
    
    print(f"✓ 打包信息已保存到: {info_file}")

def main():
    """主函数"""
    print("========================================")
    print("WMS Sample 打包前准备")
    print("========================================")
    
    # 1. 创建备份
    backup_dir = create_backup()
    
    # 2. 准备干净数据库
    if not prepare_clean_database():
        print("❌ 数据库准备失败，请检查错误信息")
        return False
    
    # 3. 更新配置文件
    if not update_config_for_packaging():
        print("❌ 配置文件更新失败，请检查错误信息")
        return False
    
    # 4. 清理开发文件
    clean_development_files()
    
    # 5. 验证打包准备情况
    if not verify_packaging_readiness():
        print("❌ 打包准备验证失败，请检查错误信息")
        return False
    
    # 6. 创建打包信息
    create_packaging_info()
    
    print("\n========================================")
    print("打包准备完成")
    print("========================================")
    print(f"备份位置: {backup_dir}")
    print("系统已准备好进行打包部署")
    print("\n下一步:")
    print("1. 使用 PyInstaller 或其他工具打包")
    print("2. 测试打包后的程序")
    print("3. 部署到目标服务器")
    print("4. 运行部署检查脚本验证")
    
    return True

if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1) 